package com.ok.event;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import com.ok.constant.WsEventEnum;
import com.ok.utils.SessionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/dcom/{message}")
@Component
@Slf4j
public class DcomWsSocket {
    /**
     * 用于保存uri对应的连接服务，{uri:WebSocketServer}，设计成线程安全的
     */
    public static ConcurrentHashMap<String, DcomWsSocket> webSocketServerMAP = new ConcurrentHashMap<>();
    /**
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    public Session session;
    /**
     * 前端传入的连接唯一标识
     */
    public String wsSessionId;
    /**
     * 用户token
     */
    public String token;
    /**
     * 连接url类型（0：心跳与告警，1：推送组态关连监测点值变动数据，2：推送实时值表格监测点数据变动）
     */
    public String urlType;
    /**
     * 用来记录当前在线连接数。设计成线程安全的。
     */
    private static final AtomicInteger onlineCount = new AtomicInteger(0);

    /**
     * 获取在线连接数
     */
    public static int getOnlineCount() {
        return onlineCount.get();
    }

    /**
     * 原子性操作，在线连接数加一
     */
    public static void addOnlineCount() {
        onlineCount.getAndIncrement();
    }

    /**
     * 原子性操作，在线连接数减一
     */
    public static void reduceOnlineCount() {
        onlineCount.getAndDecrement();
        log.info("有WS连接减少:当前连接数量:{}", getOnlineCount());
    }

    /**
     * 连接建立成功时触发，绑定参数
     *
     * @param session 可选的参数
     *                session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("message") String message) throws IOException {
        addOnlineCount(); // 在线数加1
        log.info("连接数:{},message:{}", getOnlineCount(),message);
        synchronized (DcomWsSocket.class) {
            WsEventManage.notifyWsEvent(WsEventEnum.open.getCode(), this, null);
        }
    }

    /**
     * 连接关闭时触发，注意不能向客户端发送消息了
     */
    @OnClose
    public void onClose() throws IOException {
        reduceOnlineCount();
        log.info("websocket通信连接关闭");
    }

    /**
     * 收到客户端消息后触发
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("收到消息：{}", message);
        WsEventManage.notifyWsEvent(WsEventEnum.message.getCode(), this, message);
    }

    /**
     * 通信发生错误时触发
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.info("websocket通信发生错误");
    }
}
